#ifndef _BIEUTHUC_H
#define _BIEUTHUC_H
#include <string>
#include <sstream>
#include <iostream>
using namespace std;

class BieuThuc{
private:
	BieuThuc* bieuThuc;
protected:
	BieuThuc();
	/*~BieuThuc();*/
	virtual BieuThuc* timDaoHam() = 0;
public:
	virtual double tinhGiaTri(double x) = 0;
	virtual BieuThuc* tinhDaoHam(); 
	virtual void daoDauBieuThuc() = 0;
	virtual string xuatChuoi() = 0;
};

class BieuThucHang: public BieuThuc{
	double hangSo;
	BieuThucHang();
	BieuThucHang(double hangSo);
	static BieuThucHang* ZERO;
public:
	static BieuThucHang* taoBieuThucHang(double hangSo){
		if(hangSo == 0){
		return ZERO;
	}
	else{
		return new BieuThucHang(hangSo);
	}
	};
	virtual double tinhGiaTri(double x);
	//virtual BieuThuc* tinhDaoHam();
	virtual BieuThuc* timDaoHam();
	virtual void daoDauBieuThuc();
	virtual string xuatChuoi();
};

class BieuThucDon: public BieuThuc{
	double heSo, soMu;
public:
	BieuThucDon();
	BieuThucDon(double heSo, double soMu);
	virtual double tinhGiaTri(double x);
	//virtual BieuThuc* tinhDaoHam();
	virtual BieuThuc* timDaoHam();
	virtual void daoDauBieuThuc();
	virtual string xuatChuoi();
};

class BieuThucTong: public BieuThuc{
private:
	BieuThuc* bieuThuc1;
	BieuThuc* bieuThuc2;
public:
	BieuThucTong();
	BieuThucTong(BieuThuc* bt1, BieuThuc* bt2);
	~BieuThucTong();
	virtual double tinhGiaTri(double x);
	//virtual BieuThuc* tinhDaoHam();
	virtual BieuThuc* timDaoHam();
	virtual void daoDauBieuThuc();
	virtual string xuatChuoi();
};

class BieuThucTich: public BieuThuc{
private:
	BieuThuc* bieuThuc1;
	BieuThuc* bieuThuc2;
public:
	BieuThucTich();
	BieuThucTich(BieuThuc* bt1, BieuThuc* bt2);
	~BieuThucTich();
	virtual double tinhGiaTri(double x);
	//virtual BieuThuc* tinhDaoHam();
	virtual BieuThuc* timDaoHam();
	virtual void daoDauBieuThuc();
	virtual string xuatChuoi();
};

class BieuThucChia: public BieuThuc{
private:
	BieuThuc* bieuThuc1;
	BieuThuc* bieuThuc2;
public:
	BieuThucChia();
	BieuThucChia(BieuThuc* bt1, BieuThuc* bt2);
	~BieuThucChia();
	virtual double tinhGiaTri(double x);
	//virtual BieuThuc* tinhDaoHam();
	virtual BieuThuc* timDaoHam();
	virtual void daoDauBieuThuc();
	virtual string xuatChuoi();
};
#endif